package net.chenlin.dp.config;

import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.AutoMappingBehavior;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.LocalCacheScope;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatisConfig {

	@Bean
	public ConfigurationCustomizer mybatisConfigurationCustomizer() {
		return new ConfigurationCustomizer() {
			@Override
			public void customize(org.apache.ibatis.session.Configuration config) {

				// 设置 properties
				Properties perperties = new Properties();
				perperties.setProperty("dialectClass", "net.chenlin.dp.common.orm.dialect.MySql5Dialect");
				config.setVariables(perperties);

				// 设置 plugins
				Interceptor pageResultInterceptor = new net.chenlin.dp.common.orm.plugins.PaginationResultSetHandlerInterceptor();
				Interceptor pageStatementINterceptor = new net.chenlin.dp.common.orm.plugins.PaginationStatementHandlerInterceptor();
				config.addInterceptor(pageResultInterceptor);
				config.addInterceptor(pageStatementINterceptor);

				// 全局映射器启用缓存
				config.setCacheEnabled(true);
				// 查询时，关闭关联对象即时加载以提高性能
				config.setLazyLoadingEnabled(true);
				// 对于未知的SQL查询，允许返回不同的结果集以达到通用的效果
				config.setMultipleResultSetsEnabled(true);
				// 允许使用列标签代替列名
				config.setUseColumnLabel(true);
				// 不允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值)，数据表的PK生成策略将被覆盖
				config.setUseGeneratedKeys(false);
				// 给予被嵌套的resultMap以字段-属性的映射支持 FULL,PARTIAL
				config.setAutoMappingBehavior(AutoMappingBehavior.PARTIAL);
				// 对于批量更新操作缓存SQL以提高性能 BATCH,SIMPLE
				// config.setDefaultExecutorType(ExecutorType.BATCH);
				// 数据库超过25000秒仍未响应则超时
				// config.setDefaultStatementTimeout(25000);

				// Allows using RowBounds on nested statements
				config.setSafeRowBoundsEnabled(false);
				// Enables automatic mapping from classic database column names
				// A_COLUMN to camel case classic Java property names aColumn.
				config.setMapUnderscoreToCamelCase(true);
				// MyBatis uses local cache to prevent circular references and
				// speed up repeated nested queries. By default (SESSION) all
				// queries executed during a session are cached. If
				// localCacheScope=STATEMENT local session will be used just for
				// statement execution, no data will be shared between two
				// different calls to the same SqlSession.
				config.setLocalCacheScope(LocalCacheScope.SESSION);
				// Specifies the JDBC type for null values when no specific JDBC
				// type was provided for the parameter. Some drivers require
				// specifying the column JDBC type but others work with generic
				// values like NULL, VARCHAR or OTHER.
				config.setJdbcTypeForNull(JdbcType.OTHER);
				// Specifies which Object's methods trigger a lazy load
				Set<String> ms = new HashSet<String>();
				ms.add("equals");
				ms.add("clone");
				ms.add("hashCode");
				ms.add("toString");
				config.setLazyLoadTriggerMethods(ms);
				// 设置关联对象加载的形态，此处为按需加载字段(加载字段由SQL指 定)，不会加载关联表的所有字段，以提高性能
				config.setAggressiveLazyLoading(false);
			}
		};
	}

}
